/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.benchmark.security;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.util.Properties;

import org.apache.log4j.Logger;

import cgl.narada.discovery.topics.TopicDiscoveryClient;
import cgl.narada.discovery.topics.Topics;
import cgl.narada.discovery.topics.messages.SignedTopicAdvertisement;
import cgl.narada.event.NBEvent;
import cgl.narada.event.TemplateProfileAndSynopsisTypes;
import cgl.narada.matching.Profile;
import cgl.narada.service.ServiceException;
import cgl.narada.service.client.ClientService;
import cgl.narada.service.client.EventConsumer;
import cgl.narada.service.client.NBEventListener;
import cgl.narada.service.client.SessionService;
import cgl.narada.service.qos.ConsumerConstraints;
import cgl.narada.service.security.kmc.KMCClient;
import cgl.narada.service.security.kmc.TopicRights;
import cgl.narada.service.security.kmc.messages.SecureTopicKeyResponse;
import cgl.narada.service.security.securityprovider.CertificateManager;
import cgl.narada.service.security.securityprovider.CertificateUtil;
import cgl.narada.util.SystemInit;
import cgl.narada.util.SystemNotInitializedException;

/**
 * <br>
 * Created on Apr 21, 2006
 * 
 * @author Harshawardhan Gadgil (hgadgil@grids.ucs.indiana.edu)
 */
public class DummySubscriber {

    static Logger log = Logger.getLogger("DummySubscriber");

    private class Dummy implements NBEventListener {

        int _entity;

        public void onEvent(NBEvent nbEvent) {
            // Discard Event...
            // log.info("[" + _entity + "] Got an Event !");
            nbEvent = null;
        }

        public Dummy(int entityId) {

            _entity = entityId;

            Properties prop = new Properties();

            prop.put("hostname", host);
            prop.put("portnum", port);

            try {

                System.out.println("INIT: EntityId:" + entityId);
                ClientService clientService = SessionService.getClientService(
                        entityId, configFileLocation);

                clientService.initializeBrokerCommunications(prop, protocol);

                // Profile inSecureprofile = clientService.createProfile(
                // TemplateProfileAndSynopsisTypes.STRING, "XYZ");
                //
                Profile secureprofile = clientService.createProfile(
                        TemplateProfileAndSynopsisTypes.STRING, topicUUID);

                EventConsumer dummyConsumer = clientService
                        .createEventConsumer(this);

                ConsumerConstraints cc = dummyConsumer
                        .createConsumerConstraints(secureprofile);
                cc.setReceiveSecurely(entityId);
                cc.setSecurityToken(topicKey.getSignedSecurityToken(), topicKey
                        .getKey(), null, true, rootCA);

                dummyConsumer.subscribeTo(secureprofile, cc);
                // consumer.subscribeTo(inSecureprofile);

                System.out.println("Dummy <" + entityId + "> INIT DONE ! : "
                        + topicUUID);

            } catch (ServiceException e) {
                log.error("", e);
            }
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SystemInit.init();
        new DummySubscriber(args);
    }

    String configFileLocation;
    String host;
    String port;
    String protocol;

    int A, Z;

    public DummySubscriber(String[] args) {

        host = args[0];
        port = args[1];
        protocol = args[2];

        A = Integer.parseInt(args[3]);
        Z = Integer.parseInt(args[4]);
        try {
            configFileLocation = SystemInit
                    .getInitData(SystemInit.SYS_SERVICE_CONFIG_PATH);
        } catch (SystemNotInitializedException e) {
            e.printStackTrace();
            log.error("Could not get config file");
        }

        try {
            initTopics(SystemInit.getInitData(SystemInit.SYS_KEYSTORE));
        } catch (SystemNotInitializedException e) {
            e.printStackTrace();
            log.error("Could not get keystore");
        }

        // Now generate subscribers with entityID A -> Z
        Dummy[] d = new Dummy[Z - A + 1];
        for (int i = A; i <= Z; i++) {
            d[i - A] = new Dummy(i);
        }
    }

    SecureTopicKeyResponse topicKey;
    private String topicName = "encrypted";
    String topicUUID;
    PublicKey rootCA;

    public SignedTopicAdvertisement[] discoverTopics(Certificate cert,
            PrivateKey priv, String synopsis, int matchType, int maxTopics) {

        TopicDiscoveryClient disco = new TopicDiscoveryClient(15001,
                configFileLocation, cert, priv, host, port, protocol);

        SignedTopicAdvertisement[] stas = disco.discover(matchType, synopsis,
                null, maxTopics);

        disco.close();

        return stas;
    }

    public void initTopics(String keystore) {
        CertificateManager certMan = new CertificateManager();
        certMan.init(keystore, null);

        rootCA = CertificateUtil.getPublicKey(certMan, certMan.ROOT_CA_ALIAS);

        Certificate c3_cert = CertificateUtil.getCertificate(certMan, "c3");
        PrivateKey c3_priv = CertificateUtil.getPrivateKey(certMan, "c3");

        // First discover the topic...
        SignedTopicAdvertisement[] stas = discoverTopics(c3_cert, c3_priv,
                topicName, Topics.MATCHING_STRING, 1);

        KMCClient client2 = new KMCClient(c3_cert, c3_priv, rootCA, "/kmc/c3",
                configFileLocation, host, port, protocol);

        TopicRights reqRights = new TopicRights(TopicRights.SUBSCRIBE_RIGHT);

        // Now try to get the security token...

        topicKey = client2.requestTopicKey(stas[0].getTopicAd()
                .getTopicSynopsis(), c3_cert, reqRights, 5000);

        if (topicKey == null)
            System.out.println("Request Denied / Timeout occurred !");
        else {
            System.out.println("Sec Token:"
                    + topicKey.getSignedSecurityToken().getSecurityToken()
                            .getValidity().toString());

            topicUUID = stas[0].getTopicAd().getTopicSynopsis();
        }
    }

}
